import {
  Activity,
  ActivityType,
  MoodConfig,
  User,
  UserSettings,
  CreateActivityRequest,
  UpdateActivityRequest,
  GetActivitiesRequest,
  GetActivitiesResponse,
  CreateActivityTypeRequest,
  UpdateActivityTypeRequest,
  CreateMoodConfigRequest,
  UpdateMoodConfigRequest,
  UpdateUserSettingsRequest,
  GetStatsRequest,
  GetStatsResponse,
  UploadImageRequest,
  UploadImageResponse,
} from '@/types/proto';

class APIClient {
  private baseUrl: string;
  private token?: string;

  constructor(baseUrl: string = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080') {
    this.baseUrl = baseUrl;
  }

  setToken(token: string) {
    this.token = token;
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    const url = `${this.baseUrl}${endpoint}`;
    const headers = {
      'Content-Type': 'application/json',
      ...(this.token && { Authorization: `Bearer ${this.token}` }),
      ...options.headers,
    };

    const response = await fetch(url, {
      ...options,
      headers,
    });

    if (!response.ok) {
      throw new Error(`API request failed: ${response.statusText}`);
    }

    return response.json();
  }

  // Activity Service
  async createActivity(request: CreateActivityRequest): Promise<Activity> {
    return this.request<Activity>('/api/activities', {
      method: 'POST',
      body: JSON.stringify(request),
    });
  }

  async getActivities(request: GetActivitiesRequest): Promise<GetActivitiesResponse> {
    const params = new URLSearchParams();
    params.append('page', request.page.toString());
    params.append('pageSize', request.pageSize.toString());
    params.append('sortBy', request.sortBy);
    params.append('sortOrder', request.sortOrder);
    
    if (request.activityType) params.append('activityType', request.activityType);
    if (request.mood) params.append('mood', request.mood);
    if (request.startDate) params.append('startDate', request.startDate.toISOString());
    if (request.endDate) params.append('endDate', request.endDate.toISOString());
    if (request.search) params.append('search', request.search);

    return this.request<GetActivitiesResponse>(`/api/activities?${params.toString()}`);
  }

  async getActivity(id: string): Promise<Activity> {
    return this.request<Activity>(`/api/activities/${id}`);
  }

  async updateActivity(request: UpdateActivityRequest): Promise<Activity> {
    return this.request<Activity>(`/api/activities/${request.id}`, {
      method: 'PUT',
      body: JSON.stringify(request),
    });
  }

  async deleteActivity(id: string): Promise<void> {
    await this.request(`/api/activities/${id}`, {
      method: 'DELETE',
    });
  }

  // Settings Service
  async getActivityTypes(): Promise<ActivityType[]> {
    const response = await this.request<{ activityTypes: ActivityType[] }>('/api/settings/activity-types');
    return response.activityTypes;
  }

  async createActivityType(request: CreateActivityTypeRequest): Promise<ActivityType> {
    return this.request<ActivityType>('/api/settings/activity-types', {
      method: 'POST',
      body: JSON.stringify(request),
    });
  }

  async updateActivityType(request: UpdateActivityTypeRequest): Promise<ActivityType> {
    return this.request<ActivityType>(`/api/settings/activity-types/${request.id}`, {
      method: 'PUT',
      body: JSON.stringify(request),
    });
  }

  async deleteActivityType(id: string): Promise<void> {
    await this.request(`/api/settings/activity-types/${id}`, {
      method: 'DELETE',
    });
  }

  async getMoodConfigs(): Promise<MoodConfig[]> {
    const response = await this.request<{ moodConfigs: MoodConfig[] }>('/api/settings/mood-configs');
    return response.moodConfigs;
  }

  async createMoodConfig(request: CreateMoodConfigRequest): Promise<MoodConfig> {
    return this.request<MoodConfig>('/api/settings/mood-configs', {
      method: 'POST',
      body: JSON.stringify(request),
    });
  }

  async updateMoodConfig(request: UpdateMoodConfigRequest): Promise<MoodConfig> {
    return this.request<MoodConfig>(`/api/settings/mood-configs/${request.id}`, {
      method: 'PUT',
      body: JSON.stringify(request),
    });
  }

  async deleteMoodConfig(id: string): Promise<void> {
    await this.request(`/api/settings/mood-configs/${id}`, {
      method: 'DELETE',
    });
  }

  async getUserSettings(): Promise<UserSettings> {
    return this.request<UserSettings>('/api/settings/user');
  }

  async updateUserSettings(request: UpdateUserSettingsRequest): Promise<UserSettings> {
    return this.request<UserSettings>('/api/settings/user', {
      method: 'PUT',
      body: JSON.stringify(request),
    });
  }

  // User Service
  async getUser(): Promise<User> {
    return this.request<User>('/api/user');
  }

  async getStats(request: GetStatsRequest): Promise<GetStatsResponse> {
    const params = new URLSearchParams();
    params.append('period', request.period);
    
    if (request.startDate) params.append('startDate', request.startDate.toISOString());
    if (request.endDate) params.append('endDate', request.endDate.toISOString());

    return this.request<GetStatsResponse>(`/api/user/stats?${params.toString()}`);
  }

  // File Service
  async uploadImage(request: UploadImageRequest): Promise<UploadImageResponse> {
    const formData = new FormData();
    formData.append('file', new Blob([request.imageData], { type: request.contentType }), request.filename);

    const response = await fetch(`${this.baseUrl}/api/files/upload`, {
      method: 'POST',
      headers: {
        ...(this.token && { Authorization: `Bearer ${this.token}` }),
      },
      body: formData,
    });

    if (!response.ok) {
      throw new Error(`Upload failed: ${response.statusText}`);
    }

    return response.json();
  }
}

export const apiClient = new APIClient();
export default apiClient;